package cn.tedu.bece.admin.system.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import cn.tedu.bece.admin.common.util.SecurityUtils;
import cn.tedu.bece.admin.common.constant.Constants;
import cn.tedu.bece.admin.common.exception.ServiceException;
import cn.tedu.bece.admin.system.mapper.SysUserMapper;
import cn.tedu.bece.admin.system.mapper.SysUserRoleMapper;
import cn.tedu.bece.admin.system.pojo.dto.*;
import cn.tedu.bece.admin.system.pojo.entity.SysUser;
import cn.tedu.bece.admin.system.pojo.entity.SysUserRole;
import cn.tedu.bece.admin.system.pojo.vo.SysUserDetailVO;
import cn.tedu.bece.admin.system.service.IFileService;
import cn.tedu.bece.admin.system.service.ISysUserService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;

@Transactional
@Service
public class SysUserServiceImpl implements ISysUserService {

    @Autowired
    private SysUserMapper sysUserMapper;

    @Autowired
    private SysUserRoleMapper sysUserRoleMapper;

    @Autowired
    private IFileService fileService;

    private void checkUsernameExists(String username, Long userId) {
        if (StrUtil.isEmpty(username)) {
            throw new ServiceException("用户账号不能为空");
        }
        LambdaQueryWrapper<SysUser> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(SysUser::getUsername, username);
        queryWrapper.ne(userId != null, SysUser::getId, userId);
        if (sysUserMapper.selectCount(queryWrapper) > 0) {
            throw new ServiceException("用户账号已存在");
        }
    }

    private void checkPhoneExists(String phone, Long userId) {
        if (StrUtil.isNotEmpty(phone)) {
            LambdaQueryWrapper<SysUser> queryWrapper = Wrappers.lambdaQuery();
            queryWrapper.eq(SysUser::getPhone, phone);
            queryWrapper.ne(userId != null, SysUser::getId, userId);
            if (sysUserMapper.selectCount(queryWrapper) > 0) {
                throw new ServiceException("手机号码已存在");
            }
        }
    }

    private void checkEmailExists(String email, Long userId) {
        if (StrUtil.isNotEmpty(email)) {
            LambdaQueryWrapper<SysUser> queryWrapper = Wrappers.lambdaQuery();
            queryWrapper.eq(SysUser::getEmail, email);
            queryWrapper.ne(userId != null, SysUser::getId, userId);
            if (sysUserMapper.selectCount(queryWrapper) > 0) {
                throw new ServiceException("用户邮箱已存在");
            }
        }
    }

    @Override
    public void insert(SysUserAddParam sysUserAddParam) {
        //
        checkUsernameExists(sysUserAddParam.getUsername(), null);
        checkPhoneExists(sysUserAddParam.getPhone(), null);
        checkEmailExists(sysUserAddParam.getEmail(), null);
        //
        SysUser sysUser = new SysUser();
        BeanUtils.copyProperties(sysUserAddParam, sysUser);
        if (StrUtil.isEmpty(sysUserAddParam.getPassword())) {
            sysUserAddParam.setPassword(Constants.DEFAULT_PASSWORD); // 默认密码
        }
        sysUser.setPassword(SecurityUtils.encryptPassword(sysUserAddParam.getPassword()));
        sysUser.setStatus(sysUser.getStatus() == null ? Constants.STATUS_NORMAL : sysUser.getStatus());
        // 新增用户信息
        sysUserMapper.insert(sysUser);
        // 新增用户和角色关联
        insertUserRole(sysUser.getId(), sysUserAddParam.getRoleIds());
    }

    private void insertUserRole(Long userId, List<Long> roleIds) {
        if (CollectionUtil.isNotEmpty(roleIds)) {
            List<SysUserRole> userRoleList = new ArrayList<>(roleIds.size());
            for (Long roleId : roleIds) {
                SysUserRole userRole = new SysUserRole();
                userRole.setUserId(userId);
                userRole.setRoleId(roleId);
                userRoleList.add(userRole);
            }
            sysUserRoleMapper.insertBatchUserRole(userRoleList);
        }
    }

    @Override
    public void deleteByIds(List<Long> ids) {
        if (CollectionUtil.isEmpty(ids)) {
            throw new ServiceException("参数不能为空");
        }
        // 删除用户和角色关联
        sysUserRoleMapper.deleteUserRoleByUserIds(ids);
        // 删除用户信息
        sysUserMapper.deleteBatchIds(ids);
    }

    @Override
    public void updateById(SysUserUpdateParam sysUserUpdateParam) {
        //
        checkPhoneExists(sysUserUpdateParam.getPhone(), sysUserUpdateParam.getId());
        checkEmailExists(sysUserUpdateParam.getEmail(), sysUserUpdateParam.getId());
        //
        SysUser sysUser = new SysUser();
        BeanUtils.copyProperties(sysUserUpdateParam, sysUser);
        // 修改用户信息
        sysUserMapper.updateById(sysUser);
        // 删除用户和角色关联
        sysUserRoleMapper.deleteUserRoleByUserId(sysUser.getId());
        // 新增用户和角色关联
        insertUserRole(sysUser.getId(), sysUserUpdateParam.getRoleIds());
    }

    @Override
    public void updateStatus(Long id, Integer status) {
        SysUser entity = new SysUser();
        entity.setId(id);
        entity.setStatus(status);
        sysUserMapper.updateById(entity);
    }

    @Override
    public void resetPassword(Long id) {
        SysUser sysUser = new SysUser();
        sysUser.setId(id);
        sysUser.setPassword(SecurityUtils.encryptPassword(Constants.DEFAULT_PASSWORD));
        sysUserMapper.updateById(sysUser);
    }

    @Override
    public SysUserDetailVO selectById(Long id) {
        SysUser sysUser = sysUserMapper.selectById(id);
        if (sysUser != null) {
            SysUserDetailVO sysUserDetailVO = new SysUserDetailVO();
            BeanUtils.copyProperties(sysUser, sysUserDetailVO);
            sysUserDetailVO.setRoleIds(sysUserRoleMapper.selectRoleIdsByUserId(id));
            return sysUserDetailVO;
        }
        return null;
    }

    @Override
    public List<SysUser> selectList(SysUserQuery query) {
        List<SysUser> sysUserList = sysUserMapper.selectSysUserList(query);
        if (CollectionUtil.isNotEmpty(sysUserList)) {
            sysUserList.forEach(sysUser -> sysUser.setPassword(null));
        }
        return sysUserList;
    }

    @Override
    public List<SysUser> selectListForExport() {
        return sysUserMapper.selectList(Wrappers.<SysUser>lambdaQuery().orderByAsc(SysUser::getCreateTime));
    }

    @Override
    public SysUserDetailVO selectProfile(Long userId) {
        SysUser sysUser = sysUserMapper.selectById(userId);
        if (sysUser != null) {
            SysUserDetailVO sysUserDetailVO = new SysUserDetailVO();
            BeanUtils.copyProperties(sysUser, sysUserDetailVO);
            return sysUserDetailVO;
        }
        return null;
    }

    @Override
    public void updateProfile(Long userId, SysUserProfileParam sysUserProfileParam) {
        //
        checkPhoneExists(sysUserProfileParam.getPhone(), userId);
        checkEmailExists(sysUserProfileParam.getEmail(), userId);
        //
        SysUser sysUser = new SysUser();
        BeanUtils.copyProperties(sysUserProfileParam, sysUser);
        sysUser.setId(userId);
        //
        sysUserMapper.updateById(sysUser);
    }

    @Override
    public void updatePassword(Long userId, SysUserPasswordParam sysUserPasswordParam) {
        //
        SysUser sysUser = sysUserMapper.selectById(userId);
        if (!SecurityUtils.matchesPassword(sysUserPasswordParam.getRawPassword(), sysUser.getPassword())) {
            throw new ServiceException("原密码错误");
        }
        //
        sysUser = new SysUser();
        sysUser.setId(userId);
        sysUser.setPassword(SecurityUtils.encryptPassword(sysUserPasswordParam.getNewPassword()));
        //
        sysUserMapper.updateById(sysUser);
    }

    @Override
    public void updateAvatar(Long userId, SysUserAvatarParam sysUserAvatarParam) {
        SysUser dbUser = sysUserMapper.selectById(userId);
        SysUser sysUser = new SysUser();
        sysUser.setId(userId);
        sysUser.setAvatar(sysUserAvatarParam.getAvatar());
        int rows = sysUserMapper.updateById(sysUser);
        if (rows == 0) {
            fileService.deleteByUrl(sysUserAvatarParam.getAvatar());
            throw new ServiceException("修改头像失败");
        }
        fileService.deleteByUrl(dbUser.getAvatar());
    }

}
